﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Linq.Expressions;
using JackyCode.Mock.Exceptions;
using JackyCode.Mock.Extensions;

namespace JackyCode.Mock
{
    class SetUpImpl<TEntity,TResult> : ISetUp<TResult>
    {
        private Expression<Func<TEntity, TResult>> expression;
        private MethodData methodData;
        private IMockData mockData;

        public SetUpImpl(Expression<Func<TEntity, TResult>> expression, IMockData mockData)
        {
            this.expression = expression;
            this.mockData = mockData;
            CheckMethodInfo();
        }

        private void CheckMethodInfo()
        {
            MethodInfo methodInfo = MethodData.MethodInfo;
            if (methodInfo.DeclaringType.IsClass)
            {
                if (!methodInfo.IsVirtual)
                {
                    throw new MockException(string.Format("The method [{0}] should be virtual can setup!",methodInfo.Name));
                }
            }
        }

        public MethodData MethodData
        {
            get
            {
                if (methodData == null)
                {
                    methodData = expression.ExtractAsMethodData();
                }
                return methodData;
            }
        }

        public void Returns(object returnVal)
        {
            mockData.Merge(methodData, returnVal);
        }
    }
}
